package com.hqd.ch03.v42.web.method.annotation;

import com.hqd.ch03.v42.core.MethodParameter;
import com.hqd.ch03.v42.web.context.request.NativeWebRequest;
import com.hqd.ch03.v42.web.method.support.HandlerMethodArgumentResolver;
import com.hqd.ch03.v42.web.method.support.HandlerMethodReturnValueHandler;
import com.hqd.ch03.v42.web.servlet.support.ModelAndViewContainer;
import com.hqd.ch03.v42.web.ui.Model;

public class ModelMethodProcessor implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return Model.class.isAssignableFrom(parameter.getParameterType());
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest) throws Exception {
        return mavContainer.getModel();
    }

    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return Model.class.isAssignableFrom(returnType.getParameterType());
    }

    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType,
                                  ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {

        if (returnValue == null) {
            return;
        } else if (returnValue instanceof Model) {
            mavContainer.addAllAttributes(((Model) returnValue).asMap());
        } else {
            // should not happen
            throw new UnsupportedOperationException("Unexpected return type [" +
                    returnType.getParameterType().getName() + "] in method: " + returnType.getMethod());
        }
    }
}
